/* 线程安全队列模版 */

#include <pthread.h>
#include <queue>

#define THEARD_COUNT 10000

template <class T>
class MsgQueue
{
public:
    MsgQueue()
        : _capacity(THEARD_COUNT)
    {
       pthread_mutex_init(&_q_lock, NULL);
       pthread_cond_init(&_prod_cond, NULL);
       pthread_cond_init(&_cons_cond, NULL);
    }

    ~MsgQueue()
    {
        pthread_mutex_destroy(&_q_lock);
        pthread_cond_destroy(&_prod_cond);
        pthread_cond_destroy(&_cons_cond);
    }

    void push(const T& msg)
    {
        pthread_mutex_lock(&_q_lock);
        while(_que.size() >= _capacity)
        {
            pthread_cond_wait(&_prod_cond, &_q_lock);
        }
        _que.push(msg);
        pthread_mutex_unlock(&_q_lock);

        pthread_cond_signal(&_cons_cond);
    }

    void pop(T* msg)
    {
        pthread_mutex_lock(&_q_lock);
        while(_que.empty())
        {
            pthread_cond_wait(&_cons_cond, &_q_lock);
        }
        *msg = _que.front();
        _que.pop();
        pthread_mutex_unlock(&_q_lock);
        
        pthread_cond_signal(&_prod_cond);
    }

    int GetQueValueCount()    //for test
    {
        pthread_mutex_lock(&_q_lock);
        size_t size = _que.size();
        pthread_mutex_unlock(&_q_lock);
    
        return size;
    }


private:
    /*
     * _que      ：保存消息的容器（临界资源）
     * _capacity ：容器的容量（即最大高并发的线程数量）
     * _q_lock   ：保证容器线程安全的互斥锁
     * _prod_cond：生产者线程的条件变量
     * _cons_cond：消费者线程的条件变量
     * */
    
    std::queue<T> _que;
    size_t _capacity;
    
    pthread_mutex_t _q_lock;    
    pthread_cond_t _prod_cond;
    pthread_cond_t _cons_cond;
};
